﻿using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class CardSystem : Singleton<CardSystem>
{
    [SerializeField] private HandView handView;
    [SerializeField] private Transform drawPilePoint;
    [SerializeField] private Transform discardPilePoint;
    private readonly List<Card> drawPile = new();
    private readonly List<Card> discardPile = new();
    private readonly List<Card> hand = new();

    void OnEnable()
    {
        ActionSystem.AttachPerformer<DrawCardsGA>(DrawCardPerformer);
        ActionSystem.AttachPerformer<DiscardAllCardsGA>(DiscardAllCardsPerformer);
        ActionSystem.AttachPerformer<PlayCardGA>(PlayCardPerformer);
        ActionSystem.AttachPerformer<PerformEffectGA>(PerformEffectPerformer);
        ActionSystem.SubscribeReaction<EnemyTurnGA>(EnemyTurnPreReaction, ReactionTiming.PRE);
        ActionSystem.SubscribeReaction<EnemyTurnGA>(EnemyTurnPostReaction, ReactionTiming.POST);
    }
    void OnDisable()
    {
        ActionSystem.DetachPerformer<DrawCardsGA>();
        ActionSystem.DetachPerformer<DiscardAllCardsGA>();
        ActionSystem.DetachPerformer<PlayCardGA>();
        ActionSystem.DetachPerformer<PerformEffectGA>();
        ActionSystem.UnsubscribeReaction<EnemyTurnGA>(EnemyTurnPreReaction, ReactionTiming.PRE);
        ActionSystem.UnsubscribeReaction<EnemyTurnGA>(EnemyTurnPostReaction, ReactionTiming.POST);
    }
    //Publics
    public void Setup(List<Card> deckData)
    {
        foreach (var card in deckData)
        {
            //Card card = new(cardData);
            drawPile.Add(card);
        }
    }
    //Performers
    private IEnumerator DrawCardPerformer(DrawCardsGA drawCardsGA)
    {
        int toDraw = drawCardsGA.Amount;
        while (toDraw > 0)
        {
            if (drawPile.Count == 0)
            {
                if (discardPile.Count == 0)
                {
                    Debug.Log("没有卡牌可以抽了");
                    yield break;
                }
                RefillDeck();
            }

            yield return DrawCard();
            toDraw--;
        }
    }

    private IEnumerator DiscardAllCardsPerformer(DiscardAllCardsGA discardAllCardsGA)
    {
        Debug.Log("弃掉所有手牌");
        foreach (var card in hand)
        {
            CardView cardView = handView.RemoveCard(card);
            yield return DiscardCard(cardView);
        }
        hand.Clear();
    }
    private IEnumerator PlayCardPerformer(PlayCardGA playCardGA)
    {
        // 从手牌中移除这张卡牌
        hand.Remove(playCardGA.cardView.card);
        CardView cardView = handView.RemoveCard(playCardGA.cardView.card);
        yield return DiscardCard(cardView);

        // 消耗法力值
        SpendManaGA spendManaGA = new(playCardGA.cardView.ManaNumber);
        ActionSystem.Instance.AddReaction(spendManaGA);
        yield return null;
        // Debug.Log(playCardGA.cardView.effectSystem.specialTargets[0].CurrentHealth);
        // 如果有，执行卡牌的特殊效果
        if (playCardGA.cardView.effectSystem.specialTargets?.Count > 0)
        {
            playCardGA.cardView.effectSystem.Special();
        }
        if (playCardGA.cardView.effectSystem.IsSpecialManualTarget)
        {
            playCardGA.cardView.effectSystem.ManualTargetSpecial();
            Debug.Log($"执行卡牌: {playCardGA.cardView.card.Title} 的特殊选中效果");
        }
        // 如果存在手动目标效果，执行该效果并指定目标

        if (playCardGA.cardView.effectSystem.ManualTargetEffect != null)
        {
            PerformEffectGA performEffectGA = new(playCardGA.cardView.effectSystem.ManualTargetEffect, new() { playCardGA.ManualTarget });
            ActionSystem.Instance.AddReaction(performEffectGA);
        }

        // 防御 null，确保 OtherEffects 不为空后再遍历执行自动效果
        if (playCardGA.cardView.effectSystem.OtherEffects.Count > 0)
        {
            foreach (var effectWrapper in playCardGA.cardView.effectSystem.OtherEffects)
            {
                var targets = effectWrapper.TargetMode.GetTargets();
                var performEffectGA = new PerformEffectGA(effectWrapper.Effect, targets);
                ActionSystem.Instance.AddReaction(performEffectGA);
            }
        }
    }


    private IEnumerator PerformEffectPerformer(PerformEffectGA performEffectGA)
    {
        GameAction effectAction = performEffectGA.Effect.GetGameAction(performEffectGA.Targets);
        ActionSystem.Instance.AddReaction(effectAction);
        yield return null;
    }
    //Reactions

    private void EnemyTurnPreReaction(EnemyTurnGA enemyTurnGA)
    {
        DiscardAllCardsGA discardAllCardsGA = new();
        ActionSystem.Instance.AddReaction(discardAllCardsGA);
    }
    private void EnemyTurnPostReaction(EnemyTurnGA enemyTurnGA)
    {
        DrawCardsGA drawCardsGA = new(5);
        ActionSystem.Instance.AddReaction(drawCardsGA);

    }
    //Helpers
    private IEnumerator DrawCard()
    {
        Card card = drawPile.Draw();
        CardView cardView = CardViewCreator.Instance?.CreateCardView(card, drawPilePoint);
        hand.Add(card);
        yield return handView.AddCard(cardView);
    }




    private void RefillDeck()
    {
        drawPile.AddRange(discardPile);
        discardPile.Clear();
    }
    private IEnumerator DiscardCard(CardView cardView)
    {
        discardPile.Add(cardView.card);
        cardView.transform.DOScale(Vector3.zero, 0.15f);
        Tween tween = cardView.transform.DOMove(discardPilePoint.position, 0.15f);
        yield return tween.WaitForCompletion();
        Destroy(cardView);
    }
    public List<Card> GetCurrentCards()
    {
        List<Card> allCards = new List<Card>();

        // 添加手牌
        allCards.AddRange(hand.Select(card => card));

        // 添加弃牌堆
        allCards.AddRange(discardPile.Select(card => card));

        // 添加抽牌堆
        allCards.AddRange(drawPile.Select(card => card));
        ResetAllCards();
        return allCards;
    }
    public void ResetAllCards()
    {
        drawPile.Clear();
        discardPile.Clear();
        hand.Clear();
    }

}
